#ifndef SIMPLE_FILE_STRING_STACK_H
#define SIMPLE_FILE_STRING_STACK_H

#include <string> // std::string
#include <utility> // std::move

namespace simple::file::string_stack
{
	using namespace std::literals;

	static const auto default_delimiters = R"(/\)"s;

	std::string::size_type top(const std::string& stack, const std::string& delimiters = default_delimiters);

	std::string pop(std::string& stack, const std::string& delimiters = default_delimiters);

	void drop(std::string& stack, const std::string& delimiters = default_delimiters);

	void push(std::string& stack, const std::string& content, const std::string& delimiters = default_delimiters);

	class manipulator
	{
		public:

		explicit manipulator(std::string& on, std::string delimiters = default_delimiters);

		manipulator(manipulator&& other);
		manipulator& operator=(manipulator&& other);

		~manipulator();

		void release();

		std::string pop();

		void drop();

		manipulator& push(const std::string& value) &;

		manipulator&& push(const std::string& value) &&;

		template <typename ...Args>
		manipulator& push(const std::string& value, Args... args) &
		{ push(value); return push(args...); }
		template <typename ...Args>
		manipulator&& push(const std::string& value, Args... args) &&
		{ std::move(*this).push(value); return std::move(*this).push(args...); }


		private:

		std::string* stack;
		unsigned size = 0;
		std::string delimiters;

		unsigned dec(unsigned amount = 1);

		manipulator(const manipulator& other) = default;
		manipulator& operator=(const manipulator& other) = default;

	};

} // namespace simple::file::string_stack

#endif /* end of include guard */
